<?php


namespace app\admin\common\library;


use app\admin\model\Department;
use app\admin\model\FlowInstance;
use app\admin\model\FlowTask;
use app\admin\model\Overtime;
use app\admin\model\Scheme;
use think\Exception;
use think\facade\Config;
use think\facade\Db;
use think\facade\Session;
use think\Request;

class FlowEngine
{
    /**
     * 当前请求实例
     * @var Request
     */
    protected $request = null;
    protected $admin = null;
    protected $scheme = null;
    protected $instance = null;
    protected $task = null;
    protected $currentNode = null;
    protected $nextNode = null;
    protected $stepid = null;
    protected $prefix = "";
    protected $department = null;

    public function __construct($name, $userid = '')
    {
        if ($userid) {
            $user = new \app\admin\model\Admin();
            $this->admin = $user->find($userid);
        } else {
            $this->admin = Session::get('admin');
        }
        if (!$this->admin) {
            throw new Exception('用户不存在');
        }
        $this->task = new FlowTask();
        $this->instance = new FlowInstance();
        $scheme = new Scheme();
        $this->department = new Department();
        $this->scheme = $scheme->where(['flowcode' => $name])->find();

        if (!$this->scheme) {
            throw new Exception('流程不存在');
        }
    }

    /**保存流程
     * @param array $data 业务表数据
     * @param string $instance 实例id
     * @return array 返回实例id,业务表id
     * @throws Exception
     */
    public function save($data = [], $instance = '')
    {

    }

    /**直接提交流程
     * @param $data
     * @return mixed
     * @throws Exception
     */
    public function start($data)
    {

        $instanceid = \fast\Random::uuid();
        $bizobjectid = \fast\Random::uuid();
        $ids['instanceid'] = $instanceid;
        $ids['bizobjectid'] = $bizobjectid;
        $flowTmp = $this->scheme; //当前任务
        $originator = $this->admin['id']; //当前用户
        $department = $this->department->where(['manager' => $originator])->select()->toArray();
        $group = Db::name('auth_group_access')->alias('a')->join('auth_groups g', 'a.group_id = g.id')->where(['uid' => $originator])->find(); //查看角色
        if (!empty($department)) {
            $data['fzr'] = 1; //领导
        } else {
            $data['fzr'] = 0; //员工
        }
        if ($group['name'] == "总经理") {
            $data['zjl'] = 1; //总经理
        } else {
            $data['zjl'] = 0; //不是
        }
        //由于公司内部问题财务和人事暂时合并 统称为综合运营部
        if ($group['name'] == "综合运营部") {
            $data['caiwu'] = 1; //财务
        } else {
            $data['caiwu'] = 0; //不是
        }
        $data['id'] = $bizobjectid;
        if ($data) {
            Db::table($flowTmp['bizscheme'])->strict(false)->insert($data);
        }
        if (array_key_exists('instancecode', $data)) {
            $instancecode = $data['instancecode'];
            unset($data['instancecode']);
        } else {
            $instancecode = time();
        }
//        $instance = new FlowInstance();
        //新建流程实例
        $this->instance->save([
            'id' => $instanceid,
            'originator' => $originator,
            'scheme' => $flowTmp['id'],
            'createtime' => date("Y-m-d h:i:s"),
            'instancecode' => $instancecode,
            'bizobjectid' => $bizobjectid,
            'completedtime' => date("Y-m-d H:i:s"),
            'instancestatus' => 1
        ]);
        $content = json_decode($flowTmp->flowcontent, true);
        //所有连线信息
        $lines = $content['lines'];
        //所有节点信息
        $nodes = $content['nodes'];
        $rtnNext = null;
        $nextNodeIndex = null;
        //如果是开始节点需要保存开始数据和下一个节点的代办数据
        $rtn = array_search('start', array_column($nodes, 'type'));
        $this->currentNode = $nodes[$rtn];
        $this->stepid = $this->currentNode['id'];
//        $task = new FlowTask();
        $this->task->save([
            'id' => \fast\Random::uuid(),
            'flowid' => $flowTmp['id'],
            'stepname' => $this->currentNode['name'],
            'stepid' => $this->currentNode['id'],
            'receiveid' => $this->admin['id'], //审批人
            'instanceid' => $instanceid,
            'senderid' => $this->admin['id'], //上一步审核人
            'status' => '2',
            'from_id' => $data['from_id'],
            'from_table' => $data['from_table'],
            'createtime' => date("Y-m-d H:i:s"),
            'completedtime' => date("Y-m-d H:i:s"),
            'comment' => '提交'
        ]);
//        //        //新增
//        $res = Db::name($data['from_table'])->where(['id' => $data['from_id']])->find();
//        if ($res['status'] == -1) {
//            Db::name($data['from_table'])->where(['id' => $data['from_id']])->update(['status' => 1]);
//        }
        $nextNodeArray = array_filter($lines, function ($t) {
            return $t['from'] == $this->stepid;
        });

        $all = count($nextNodeArray);
        $normal = 0;
        foreach ($nextNodeArray as $line) {
            //judging condition
            if (array_key_exists('setInfo', $line['data'])) {
                try {
                    $express = $line['data']['setInfo']['express'] == '' ? '1=1' : $line['data']['setInfo']['express'];
                    $sql = "select * from (select * from " . $flowTmp->bizscheme . " where id = '" . $bizobjectid . "') a where  " . $express;
                    $table = Db::query($sql);
                    if (count($table) < 1) {
                        $normal++;
                        continue;
                    }
                } catch (\think\Exception $e) {
                    continue;
                    Db::name('admin_log')->insert([
                        'admin_id' => $this->admin['id'], 'url' => '', 'title' => '流程条件异常', 'content' => $e->getMessage(), 'createtime' => time()
                    ]);
                    throw new Exception('流程条件异常,请联系管理员');
                }
            }
            if ($normal == $all) {
                Db::name('admin_log')->insert([
                    'admin_id' => $this->admin['id'], 'url' => '', 'title' => '流程异常', 'content' => '流程无法找到下一个节点'
                ]);
                throw new Exception('流程无法找到下一个节点');
            }
//            //find node where id is line's id
            $this->nextNode = array_filter($nodes, function ($t) use ($line) {
                return $t['id'] == $line['to'];
            });

            $this->nextNode = array_values($this->nextNode)[0];
            $stepName = $this->nextNode['name'];

            if ($stepName == "结束") {
                if (count($nextNodeArray) == 1 && $this->nextNode['name'] == '结束') {
                    //更改当前实例为结束
                    $this->instance->where('id', $instanceid)->update(['instancestatus' => 2, 'completedtime' => date("Y-m-d H:i:s")]);
                    //插入结束节点task
                    Db::name("flow_task")->insert([
                        'id' => \fast\Random::uuid(),
                        'flowid' => $flowTmp['id'],
                        'stepname' => $this->nextNode['name'],
                        'stepid' => $this->nextNode['id'],
                        'receiveid' => '',
                        'instanceid' => $instanceid,
                        'senderid' => $this->admin['id'],
                        'status' => '2',
                        'from_id' => $data['from_id'],
                        'from_table' => $data['from_table'],
                        'createtime' => date("Y-m-d H:i:s"),
                        'completedtime' => date("Y-m-d H:i:s"),
                        'comment' => '结束'
                    ]);
                }
                break;
            }
            $nodeType = $this->nextNode['setInfo']['nodeDesignate'];
            $dataset = [];
            $userList = [];

            if ($nodeType == "user") { //用户
                if (is_array($this->nextNode['setInfo']['NodeDesignateData']['users'])) {
                    $userList = $this->nextNode['setInfo']['NodeDesignateData']['users'];
                } else {
                    $userList = strlen($this->nextNode['setInfo']['NodeDesignateData']['users']) > 0 ? explode(',', $this->nextNode['setInfo']['NodeDesignateData']['users']) : [];
                }
                foreach ($userList as $user) {
                    $dataset = [
                        'id' => \fast\Random::uuid(),
                        'flowid' => $flowTmp['id'],
                        'stepname' => $this->nextNode['name'],
                        'stepid' => $this->nextNode['id'],
                        'receiveid' => $user,
                        'instanceid' => $instanceid,
                        'senderid' => $this->admin['id'],
                        'from_id' => $data['from_id'],
                        'from_table' => $data['from_table'],
                        'status' => '0',
                        'createtime' => date("Y-m-d H:i:s")
                    ];
                    FlowTask::create($dataset);
                }
            }
            if ($nodeType == 'dept') { //上级领导
                $userList = $this->getdeptmanager($originator);
                foreach ($userList as $user => $v) {
                    $dataset = [
                        'id' => \fast\Random::uuid(),
                        'flowid' => $flowTmp['id'],
                        'stepname' => $this->nextNode['name'],
                        'stepid' => $this->nextNode['id'],
                        'receiveid' => $v['manager'],
                        'instanceid' => $instanceid,
                        'senderid' => $this->admin['id'],
                        'from_id' => $data['from_id'],
                        'from_table' => $data['from_table'],
                        'status' => '0',
                        'createtime' => date("Y-m-d H:i:s")
                    ];
                    FlowTask::create($dataset);
                }
            }
            if ($nodeType == 'role') { //角色
                $role = '';
                if (is_array($this->nextNode['setInfo']['NodeDesignateData']['role'])) {
                    $role = $this->nextNode['setInfo']['NodeDesignateData']['role'];
                    if (!$role) {
                        throw new Exception('找不到角色');
                    } else {
                        $role = $role[0];
                    }
                } else {
                    $role = $this->nextNode['setInfo']['NodeDesignateData']['role'];
                }
                $userList = $this->getuserbyrole($role);

                foreach ($userList as $user => $v) {
                    $dataset = [
                        'id' => \fast\Random::uuid(),
                        'flowid' => $flowTmp['id'],
                        'stepname' => $this->nextNode['name'],
                        'stepid' => $this->nextNode['id'],
                        'receiveid' => $v['id'],
                        'instanceid' => $instanceid,
                        'senderid' => $this->admin['id'],
                        'from_id' => $data['from_id'],
                        'from_table' => $data['from_table'],
                        'status' => '0',
                        'createtime' => date("Y-m-d H:i:s")
                    ];
                    FlowTask::create($dataset);
                }
            }
            if (count($userList) == 0) {
                $dataset = [
                    'id' => \fast\Random::uuid(),
                    'flowid' => $flowTmp['id'],
                    'stepname' => $this->nextNode['name'],
                    'stepid' => $this->nextNode['id'],
                    'receiveid' => '',
                    'instanceid' => $instanceid,
                    'senderid' => $this->admin['id'],
                    'from_id' => $data['from_id'],
                    'from_table' => $data['from_table'],
                    'status' => '0',
                    'createtime' => date("Y-m-d H:i:s")
                ];
                FlowTask::create($dataset);
            }
        }
        return $ids;
    }


    /** 审批流程
     * @param $taskid
     * @param string $data
     * @param string $comment
     * @return bool
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function next($taskid, $data = [], $comment = '')
    {
        $res = true;
        $confluence = null;
        $task = $this->task->where(['id' => $taskid])->where('status', 0)->find();
        $instance = $this->instance->find($task['instanceid']);
        $bizobjectid = $instance->bizobjectid;
        $originator = $instance['originator'];
        $flowTmp = $this->scheme;
        $this->stepid = $task['stepid'];
        //更改当前任务为完成
        $comment = $comment == '' ? '[同意]' : $comment;
        $instanceid = $task['instanceid'];
       $this->task->where('id', $taskid)->update(['status' => 2, 'completedtime' => date("Y-m-d H:i:s"), 'comment' => $comment]);
        //判断当前节点还是否有其他任务
        $unfinishList = $this->task->where(['instanceid' => $instanceid, 'stepid' => $this->stepid])->where('status', 'in', [0, 1])->find();
        //找到当前节点
        //寻找下一个待办任务
        $content = json_decode($flowTmp->flowcontent, true);
        //所有连线信息
        $lines = $content['lines'];
        //所有节点信息
        $nodes = $content['nodes'];
        $rtnNext = null;
        $rtn = array_search($this->stepid, array_column($nodes, 'id'));
        $this->currentNode = $nodes[$rtn];
        $confluence = isset($this->currentNode['setInfo']['confluence']) ? $this->currentNode['setInfo']['confluence'] : 'all';
        //如果是第一个节点  先保存数据
        if ($task['stepname'] == '开始') {
            $this->instance->where('id', $task['instanceid'])->update(['instancestatus' => 1]);
            if (!$data['id']) {
                Db::table($flowTmp['bizscheme'])->insert($data);
            } else {
                Db::table($flowTmp['bizscheme'])->where(['id' => $data['id']])->update($data);
            }
        }
        if ($unfinishList) {
            $this->task->where(['instanceid' => $instanceid, 'stepid' => $this->stepid])->where('status', 'in', [0, 1])->update(['status' => 2]);
        }
        $nextNodeIndex = null;

        $nextNodeArray = array_filter($lines, function ($t) {
            return $t['from'] == $this->stepid;
        });
        $all = count($nextNodeArray);

        $normal = 0;
        foreach ($nextNodeArray as $line) {

            //judging condition
            if (array_key_exists('setInfo', $line['data'])) {
                try {
                    $express = $line['data']['setInfo']['express'] == '' ? '1=1' : $line['data']['setInfo']['express'];
                    $sql = "select * from (select * from " . $flowTmp->bizscheme . " where id = '" . $bizobjectid . "') a where " . $express;
                    $table = Db::query($sql);
                    if (count($table) < 1) {
                        $normal++;
                        continue;
                    }
                } catch (\think\Exception $e) {
                    Db::name('admin_log')->insert([
                        'admin_id' => $this->admin['id'], 'url' => '', 'title' => '流程条件异常', 'content' => $e->getMessage(), 'createtime' => time()
                    ]);
                    throw new Exception('流程条件异常,请联系管理员');
                }
            }
            // can not find next node
            if ($normal == $all) {
                Db::name('admin_log')->insert([
                    'admin_id' => $this->admin['id'], 'url' => '', 'title' => '流程异常', 'content' => '流程无法找到下一个节点'
                ]);
                throw new Exception('流程无法找到下一个节点');
            }
            $this->nextNode = array_filter($nodes, function ($t) use ($line) {
                return $t['id'] == $line['to'];
            });
            $this->nextNode = array_values($this->nextNode)[0]; //0表示获取他的value
            $nodeType = null;
            $dataset = [];
            $userList = null;
            if (count($nextNodeArray) == 2 && $this->nextNode['name'] == '结束') { //不确定是否存在BUG
                //更改当前实例为结束
                $this->instance->where('id', $task['instanceid'])->update(['instancestatus' => 2, 'completedtime' => date("Y-m-d H:i:s")]);
                //插入结束节点task
                Db::name("flow_task")->insert([
                    'id' => \fast\Random::uuid(),
                    'flowid' => $flowTmp['id'],
                    'stepname' => $this->nextNode['name'],
                    'stepid' => $this->nextNode['id'],
                    'receiveid' => '',
                    'instanceid' => $instanceid,
                    'senderid' => $this->admin['id'],
                    'status' => '2',
                    'from_id' => $task['from_id'],
                    'from_table' => $task['from_table'],
                    'createtime' => date("Y-m-d H:i:s"),
                    'completedtime' => date("Y-m-d H:i:s"),
                    'comment' => '结束'
                ]);
                if ($task['from_table'] == "journals") {
                    Db::name($task['from_table'])->where(['id' => $task['from_id']])->update(['status' => 2, 'journal_level_id' => $data['journal_level_id'], 'approval_admin_id' => $this->admin['id']]);
                } else {
                    Db::name($task['from_table'])->where(['id' => $task['from_id']])->update(['status' => 2]);
                }
                $this->jbsc($task['from_id'],$task['from_table']);
            }
            if (count($nextNodeArray) == 1 && $this->nextNode['name'] == '结束') {
                //更改当前实例为结束
                $this->instance->where('id', $task['instanceid'])->update(['instancestatus' => 2, 'completedtime' => date("Y-m-d H:i:s")]);
                //插入结束节点task
                Db::name("flow_task")->insert([
                    'id' => \fast\Random::uuid(),
                    'flowid' => $flowTmp['id'],
                    'stepname' => $this->nextNode['name'],
                    'stepid' => $this->nextNode['id'],
                    'receiveid' => '',
                    'instanceid' => $instanceid,
                    'senderid' => $this->admin['id'],
                    'status' => '2',
                    'from_id' => $task['from_id'],
                    'from_table' => $task['from_table'],
                    'createtime' => date("Y-m-d H:i:s"),
                    'completedtime' => date("Y-m-d H:i:s"),
                    'comment' => '结束'
                ]);
                if ($task['from_table'] == "journals") {
                    Db::name($task['from_table'])->where(['id' => $task['from_id']])->update(['status' => 2, 'journal_level_id' => $data['journal_level_id'], 'approval_admin_id' => $this->admin['id']]);
                } else {
                    Db::name($task['from_table'])->where(['id' => $task['from_id']])->update(['status' => 2]);
                }
                $this->jbsc($task['from_id'],$task['from_table']);
            }
            if ($this->nextNode['name'] != '结束') {
                $nodeType = $this->nextNode['setInfo']['nodeDesignate'];
                if ($nodeType == 'user') {
                    if (is_array($this->nextNode['setInfo']['NodeDesignateData']['users'])) {
                        $userList = $this->nextNode['setInfo']['NodeDesignateData']['users'];
                    } else {
                        $userList = explode(',', $this->nextNode['setInfo']['NodeDesignateData']['users']);
                    }
                    foreach ($userList as $user) {
                        $dataset[] = [
                            'id' => \fast\Random::uuid(),
                            'flowid' => $flowTmp['id'],
                            'stepname' => $this->nextNode['name'],
                            'stepid' => $this->nextNode['id'],
                            'receiveid' => $user,
                            'instanceid' => $instanceid,
                            'senderid' => $this->admin['id'],
                            'status' => '0',
                            'from_id' => $task['from_id'],
                            'from_table' => $task['from_table'],
                            'createtime' => date("Y-m-d H:i:s")
                        ];
                    }
                }
                if ($nodeType == 'dept') {
                    $userList = $this->getdeptmanager($originator);
                    foreach ($userList as $user => $v) {
                        $dataset[] = [
                            'id' => \fast\Random::uuid(),
                            'flowid' => $flowTmp['id'],
                            'stepname' => $this->nextNode['name'],
                            'stepid' => $this->nextNode['id'],
                            'receiveid' => $v['manager'],
                            'instanceid' => $instanceid,
                            'senderid' => $this->admin['id'],
                            'status' => '0',
                            'from_id' => $task['from_id'],
                            'from_table' => $task['from_table'],
                            'createtime' => date("Y-m-d H:i:s")
                        ];
                    }
                }
                if ($nodeType == 'role') {
                    $role = '';
                    if (is_array($this->nextNode['setInfo']['NodeDesignateData']['role'])) {
                        $role = $this->nextNode['setInfo']['NodeDesignateData']['role'];
                        if (!$role) {
                            throw new Exception('找不到角色');
                        } else {
                            $role = $role[0];
                        }
                    } else {
                        $role = $this->nextNode['setInfo']['NodeDesignateData']['role'];
                    }
                    $userList = $this->getuserbyrole($role);
                    foreach ($userList as $user => $v) {
                        $dataset[] = [
                            'id' => \fast\Random::uuid(),
                            'flowid' => $flowTmp['id'],
                            'stepname' => $this->nextNode['name'],
                            'stepid' => $this->nextNode['id'],
                            'receiveid' => $v['id'],
                            'instanceid' => $instanceid,
                            'senderid' => $this->admin['id'],
                            'status' => '0',
                            'from_id' => $task['from_id'],
                            'from_table' => $task['from_table'],
                            'createtime' => date("Y-m-d H:i:s")
                        ];
                    }
                }
                if (count($userList) == 0) {
                    $dataset[] = [
                        'id' => \fast\Random::uuid(),
                        'flowid' => $flowTmp['id'],
                        'stepname' => $this->nextNode['name'],
                        'stepid' => $this->nextNode['id'],
                        'receiveid' => '',
                        'instanceid' => $instanceid,
                        'senderid' => $this->admin['id'],
                        'status' => '0',
                        'from_id' => $task['from_id'],
                        'from_table' => $task['from_table'],
                        'createtime' => date("Y-m-d H:i:s")
                    ];
//                    Db::name('flow_mail')->insert([
//                        'subject' => '无审批人',
//                        'content' => '实例id' . $instanceid . ' 无审批人请及时处理',
//                        'createdtime' => date('Y-m-d H:i:s'),
//                        'issend' => '0',
//                        'senddate' => '0000-00-00 00:00:00',
//                        'address' => $this->getemail($flowTmp->flowcanuser),
//                        'message' => ''
//                    ]);
                }
                $this->task->saveAll($dataset, false);
            }
        }
////
//        if (!$unfinishList || ($unfinishList && $confluence == 'any')) {
//
//
//        }
        return $res;
    }


    /**
     * @param $overtime_ids
     * @param $day
     * @User: 刘海龙
     * @Date: 2021/4/27
     * @Time: 11:16
     * 处理加班时间业务逻辑
     */
     public function jbsc($id,$table){

         //当表为调休请假表的时候进入业务逻辑
         if ($table === 'vacations') {
             //查找当前请假记录
             $vacation = Db::name($table)->find($id);
             if ($vacation['alternative_id'] === 7 && $vacation['alternative_title'] === '调休') {
                 //$res['corresponding'] 当前关联的加班单的id
                 $overtime_ids = $vacation['corresponding'];
                 $zongsc= \app\admin\model\Overtime::where('id', 'in', $overtime_ids)->sum('duration'); //总时长
                 $tiaoxiusc= $vacation['day']; //调休时长
                 if ($zongsc > $tiaoxiusc) { //删除后新增
                     //当前ids $overtime_ids
                     $res     = Overtime::where('id', 'in',
                         $overtime_ids)->find();
                     $now     = date("Y-m-d H:i", time()); //当前时间
                     $scc     = $zongsc - $tiaoxiusc; //时长差
                     $scc_arr = explode('.', $scc); //转成数组
                     if (count($scc_arr) > 1) { //如果时长存在半个小时，直接在当前时间段相加
                         $end_time = date("Y-m-d H:i",
                             strtotime($now . "+" . $scc_arr[0] .
                                 " hours")); //加整数时长
                         $end_time = date("Y-m-d H:i", strtotime($end_time .
                             "+30 minutes")); //加已半个小时为单位的时长
                     } else {
                         $end_time = date("Y-m-d H:i",
                             strtotime($now . "+" . $scc_arr[0] . " hours"));
                     }
                     $info = [
                         'user_id'    => $res->user_id,
                         'user_name'  => $res->user_name,
                         'group_id'   => $res->group_id,
                         'group_name' => $res->group_name,
                         'start_time' => $now,
                         'end_time'   => $end_time,
                         'content'    => '来自' . $res->user_name . '调休剩余时长,来源于加班编号' . $overtime_ids,
                         'status'     => $res['status'],
                         "flow_id"    => $res['flow_id'],
                         'ly_id'      => $overtime_ids,
                         "is_leave"   => 0,
                         "duration"   => $scc,
                     ];
                     //更新当前使用过后的加班时间段 暂不删除,直接更新当前状态，方便查看
                     $overtime = new Overtime();
                     $syhsc    = $overtime->where('id', 'in', $overtime_ids)->select()->each(function ($item, $key) {
                                 $item['is_leave'] = 2; //更改当前状态
                             })->toArray();
                     $overtime->saveAll($syhsc);
                     //新增剩余时长记录入库
                     $create =  Overtime::create($info);
                     return $create;
                 } else {
                     if ($zongsc == $tiaoxiusc) { //直接更改已使用的状态
                         return Overtime::where('id', 'in',$overtime_ids)->update(['is_leave' => 2]);
                     } else {
                         if ($tiaoxiusc > $this->sum_jbd) {
                             return 400;
                         }
                     }
                 }
             }

         }
     }


    /**拒绝流程
     * @param $taskid
     * @param string $comment
     * @return bool
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function refuse($taskid, $comment = '')
    {
        $res = true;
        $task = $this->task->where(['id' => $taskid, 'status' => 0])->find();
        if (!$task)
            throw new Exception('找不到当前任务,或已处理，请联系管理员');
        //更改当前流程为拒绝状态
        $comment = $comment == '' ? '[拒绝]' : $comment;
        Db::name('flow_task')->where('id', $taskid)
            ->update(['status' => 2, 'completedtime' => date("Y-m-d H:i:s"), 'comment' => $comment]);
        //取消其他流程
        Db::name('flow_task')->where(['instanceid' => $task['instanceid'], 'status' => 0])
            ->update(['status' => 3, 'completedtime' => date("Y-m-d H:i:s")]);
        //更改流程实例为草稿状态
        Db::name('flow_instance')->where(['id' => $task['instanceid']])
            ->update(['instancestatus' => 0]);
        //处理加班
        if($task['from_table'] === 'vacations'){
            $vacation =  Db::name($task['from_table'])->find($task['from_id']);
            //判断是否是调休
            if ($vacation['alternative_id'] === 7 && $vacation['alternative_title'] === '调休') {
                $overtime = new Overtime();
                $syhsc    = $overtime->where('id', 'in', $vacation['corresponding'])->select()->each(function ($item, $key) {
                    $item['is_leave'] = 0; //拒绝后状态改为未使用状态
                })->toArray();
                $overtime->saveAll($syhsc);
            }
        }
        //新增
        Db::name($task['from_table'])->where(['id' => $task['from_id']])->update(['status' => '-1']);
        //寻找下一个待办任务
        $startNode = $this->task->where(['instanceid' => $task['instanceid'], 'stepname' => '开始'])->find();
        //$startNode->status = 0;
        $this->task->insert([
            'id' => \fast\Random::uuid(),
            'flowid' => $startNode['flowid'],
            'stepname' => $startNode['stepname'],
            'stepid' => $startNode['stepid'],
            'receiveid' => $startNode['receiveid'],
            'instanceid' => $startNode['instanceid'],
            'senderid' => $startNode['senderid'],
            'status' => '0',
            'createtime' => date("Y-m-d H:i:s"),
            'from_id' => $task['from_id'],
            'from_table' => $task['from_table'],
        ]);
//        //新增
//        Db::name($task['from_table'])->where(['id' => $task['from_id']])->update(['status' => '-1']);
        return $res;
    }

    /**取消流程
     * @param $taskid
     * @param string $comment
     * @return bool
     * @throws \think\exception\DbException
     */
    public function cancel($taskid, $comment = '')
    {
        $res = true;
        $task = $this->task->get($taskid);
        $comment = $comment == '' ? '[取消]' : $comment;
        //更改当前流程为取消状态
        $this->task->where(['instanceid' => $task['instanceid']])->where('status', 'in', [0, 1])->update(['status' => 3, 'completedtime' => date("Y-m-d H:i:s"), 'comment' => $comment]);
        $this->instance->where(['id' => $task['instanceid']])->update(['instancestatus' => 3]);
        return $res;
    }

    /**根据角色获取用户
     * @param $role
     * @return mixed
     */
    public function getuserbyrole($role)
    {
        $sql = "SELECT a.id FROM admins a 
                LEFT JOIN auth_group_access b ON a.id = b.uid
                LEFT JOIN auth_groups c ON b.group_id=c.id
                WHERE c.`id`='" . $role . "'";
        $user = Db::query($sql);
        return $user;
    }

    /**
     * 获取发起人当前部门负责人
     */
    public function getdeptmanager($originator)
    {
        $sql = "select manager from admins a 
               left join flow_department b on a.department_id=b.id where a.id=" . $originator;
        $user = Db::query($sql);
        return $user;
    }
}
